/**
 * @Singleton.as
 *
 * @author sodaChen mail:asframe@qq.com
 * @version 1.0
 * <br>Copyright (C), 2010-2016 asFrame.com
 * <br>This program is protected by copyright laws.
 * <br>Program Name:ASFrame
 * <br>Date:2012-10-29
 */
package com.asframe.pattern
{
	import com.asframe.collections.maps.HashMap;

	import flash.errors.IllegalOperationError;
	import flash.utils.getQualifiedClassName;
	import com.asframe.lang.IDestory;

	/**
	 * 所有单例的基类，做了单例的基础检查。所有子类最好都写一个getInstance的静态方法来获取
	 * @author sodaChen
	 * Date:2012-10-29
	 */
	public class Singleton implements IDestory
	{
		private static var classMap:HashMap = new HashMap();

		public function Singleton()
		{
			var clazz:Class = this["constructor"] as Class;
			//防止重复实例化
			if (classMap.hasKey(clazz))
				throw new IllegalOperationError(getQualifiedClassName(this)+" 只允许实例化一次！");
			else
				classMap.put(clazz,this);
		}
		// 注意，Singleton是要替换成你自己实现的子类 这里没有实际的作用
		private static var instance:Singleton;
		/**
		 * 获取实例的静态方法实例
		 * @return
		 *
		 */
		public static function getInstance():Singleton
		{
			if(instance == null)
			{
				instance = new Singleton();
			}
			return instance;
		}

		/**
		 * 销毁方法。事实上单例是很少进行销毁的
		 */
		public function destroy(o:* = null):void
		{
			classMap.remove(this["constructor"]);
			onDestroy();
		}
		protected function onDestroy():void
		{

		}
		/**
		 * 删除单例的实例（不对单例本身做任何的销毁，只是删除他的引用）
		 * @param clazz 单例的Class对象
		 *
		 */
		public static function removeInstance(clazz:Class):void
		{
			classMap.remove(clazz);
		}
		/**
		 * 获取单例类，若不存在则创建.所有的单例创建的时候，都必须使用这个方法来创建，这样可以做到统一管理单例
		 * @param clazz	任意需要实现单例效果的类
		 * @return
		 *
		 */
		public static function getInstanceOrCreate(clazz:Class):*
		{
			var obj:* = classMap.get(clazz);
			if ( obj == null )
			{
				obj = new clazz();
				//不是Singleton的子类，则手动添加Singleton构造器会自动添加到classMap
				if((!obj is Singleton))
					classMap.put(clazz,obj)
			}
			return obj;
		}
	}
}